trigger CandidateAddressValidation on Candidate__c (after insert, after update, before update) {
	// We only call the async method if this trigger was fired from the UI, not from a batch API call
	if (Trigger.new.size() == 1){ 
		// If this is an insert we always do the async call
		if (Trigger.isInsert) { AddressValidator.validateAddress(Trigger.new[0].id); }
		
		// If this is an update, we check the AsyncValidationFlag to see if this address has been validated already
		// If already validated (flag==true) then we don't do the callout again
		// Only do the callout when the asyncvalidationflag is false
		if (Trigger.isUpdate){
			if (Trigger.isBefore) {
				// in the before we just check to see if the streets, city, or state have changed (NOTE: not zip since that is changed by the async method)
				// if one of them has changed, we change the flag to be false
				if ((Trigger.new[0].Street_Address_1__c != Trigger.old[0].Street_Address_1__c) ||
					(Trigger.new[0].Street_Address_2__c != Trigger.old[0].Street_Address_2__c) ||
					(Trigger.new[0].City__c != Trigger.old[0].City__c) ||
					(Trigger.new[0].State_Province__c != Trigger.old[0].State_Province__c)) {
					// if one of the above fields changed then reset the flag so the record gets picked up by the async call
					Trigger.new[0].AsyncValidationFlag__c = false;	
				}
				System.debug('\ncandidate=' + Trigger.new[0] + '\n');
			} else {
				if (!Trigger.new[0].asyncvalidationflag__c){
					AddressValidator.validateAddress(Trigger.new[0].id); 
				}
			}
		}
	}
}